#include "hplczkysdefine.h"
#include "hplczkyscheckpacket.h"
#include "hplczkyspfcid.h"
#include "hplczkyspacketformat.h"
#include "hplczkysprotocolcommondata.h"
#include <QDebug>
#include "debug.h"

namespace hplc
{
namespace zkys
{

hplc::zkys::HplcZkysCheckPacket::HplcZkysCheckPacket(hplc::zkys::HplcZkysProtocolCommonData &data, QObject *parent)
    : QObject (parent)
{
    m_d = &data;

    m_d->m_retryNumber = RETRANSMIT_COUNT;
    m_d->m_tickCheckNumber = 3; // 3次没有收到心跳包，则表示断线
}

HplcZkysCheckPacket::~HplcZkysCheckPacket()
{

}

void HplcZkysCheckPacket::replyCheck(char *data)
{
    m_d->m_retryTimerStart = false;
    m_d->m_retryCount = 0;
    quint8 sendPfc = m_d->m_txBufferBeforeEscapeList.first().at(1);

//    PrintData(m_d->m_txBufferBeforeEscapeList.first(), "send before escape packet to reply : ");
//    PrintData(m_d->m_txBufferAfterEscapeList.first(), "send after escape packet to reply : ");

    switch (sendPfc)
    {
        case PFC_GLOBAL_EXT_SYSTEM:
        case PFC_GLOBAL_EXT_USER:
        case PFC_PUMP_EXT_SYSTEM:
        case PFC_PUMP_EXT_USER:
        case (PFC_GLOBAL_EXT_SYSTEM | 0x80):
        case (PFC_GLOBAL_EXT_USER | 0x80):
        case (PFC_PUMP_EXT_SYSTEM | 0x80):
        case (PFC_PUMP_EXT_USER | 0x80):
        {
            quint8 sendPfce = m_d->m_txBufferBeforeEscapeList.first().at(2);
            quint8 pfc = data[0];
            quint8 pfce = data[1];
            quint8 code = data[2];
            if (pfc == sendPfc && pfce == sendPfce) // 与发送的功能码一样
            {
                if (code == ZKYS_REPLY_PEC_NONE)
                {
                    // 收到回复，如果发送队列还有数据，则发送
                    ack2Send();
                }
                else
                {
                    // 帧错误
                    qWarning() << "Wrong Frame" << code;
                    emit errorPacket();
                    ack2Send();
                }
            }
            else
            {
                qDebug() << "error reply" << pfc;
            }
        }
        break;
        default:
        {
            quint8 pfc = data[0];
            quint8 code = data[1];
            if (pfc == sendPfc) // 与发送的功能码一样
            {
                if (code == ZKYS_REPLY_PEC_NONE)
                {
                    // 收到回复，如果发送队列还有数据，则发送
                    ack2Send();
                }
                else
                {
                    // 帧错误
                    qWarning() << "Wrong Frame" << code;
                    emit errorPacket();
                    ack2Send();
                }
            }
            else
            {
                qDebug() << "error reply" << pfc;
            }
        }
        break;
    }

}

HplcZkysSendCommonPacket *HplcZkysCheckPacket::getSender()
{
    return static_cast<HplcZkysSendCommonPacket*>(m_d->m_sender);
}

void HplcZkysCheckPacket::sendRetry()
{
    m_d->m_txBufferBeforeEscapeList << m_d->m_txBufferBeforeEscape;
    m_d->m_txBufferAfterEscapeList << m_d->m_txBuffer;

    if (m_d->m_txBufferAfterEscapeList.size() == 1)
    {
        m_d->m_retryTimerStart = true;
        m_d->m_retryTimerCount = 0;
        emit m_d->m_sender->requestSend(m_d->m_txBufferAfterEscapeList.first());
    }
}

void HplcZkysCheckPacket::sendNoRetry()
{
    emit m_d->m_sender->requestSend(m_d->m_txBuffer);
}

void HplcZkysCheckPacket::ack2Send()
{
    if (m_d->m_txBufferAfterEscapeList.size())
    {
        m_d->m_txBufferAfterEscapeList.removeFirst();
        m_d->m_txBufferBeforeEscapeList.removeFirst();
        if (m_d->m_txBufferAfterEscapeList.size())
        {
            m_d->m_retryTimerStart = true;
            m_d->m_retryTimerCount = 0;
            emit m_d->m_sender->requestSend(m_d->m_txBufferAfterEscapeList.first());
        }
    }
}

void HplcZkysCheckPacket::resetTickCheck()
{
    m_d->m_tickCheckCount = 0;

    m_d->m_tickCheckTimerStart = true;
    m_d->m_tickCheckTimerCount = 0;
}

void HplcZkysCheckPacket::onRetryTimeout()
{
    if (m_d->m_txBufferAfterEscapeList.size())
    {
        m_d->m_retryCount++;
        if (m_d->m_retryCount > m_d->m_retryNumber)
        {
            m_d->m_retryCount = 0;

            m_d->m_txBufferAfterEscapeList.removeFirst();
            m_d->m_txBufferBeforeEscapeList.removeFirst();

            emit lostPacket();

            qDebug() << "retry count overflow";
        }

        if (m_d->m_txBufferAfterEscapeList.size())
        {
            m_d->m_retryTimerStart = true;
            m_d->m_retryTimerCount = 0;
            emit m_d->m_sender->requestSend(m_d->m_txBufferAfterEscapeList.first());
        }
    }
}

void HplcZkysCheckPacket::onTickCheckTimeout()
{
    m_d->m_tickCheckCount++;
    if (m_d->m_tickCheckCount > m_d->m_tickCheckNumber)
    {
        m_d->m_tickCheckCount = 0;

        emit lostTick();

//        qDebug() << "tick count overflow";
    }
}

void HplcZkysCheckPacket::onBaseTickTimeout()
{
    if (m_d->m_tickTimerStart)
    {
        m_d->m_tickTimerCount += BASE_TICK_MS;
        if (m_d->m_tickTimerCount >= TICK_TIMEOUT)
        {
            m_d->m_tickTimerCount = 0;

            // 发送心跳包
            getSender()->setTick();
        }
    }

    if (m_d->m_tickCheckTimerStart)
    {
        m_d->m_tickCheckTimerCount += BASE_TICK_MS;
        if (m_d->m_tickCheckTimerCount >= TICK_TIMEOUT)
        {
            m_d->m_tickCheckTimerCount = 0;
            onTickCheckTimeout();
        }
    }

    if (m_d->m_retryTimerStart)
    {
        m_d->m_retryTimerCount += BASE_TICK_MS;
        if (m_d->m_retryTimerCount >= RETRANSMIT_TIMEOUT)
        {
            m_d->m_retryTimerCount = 0;
            onRetryTimeout();
        }
    }
}

} // zkys
} // hplc
